package com.tcs.monitoring.task.impl;

import java.util.Date;

import org.hyperic.sigar.CpuInfo;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tcs.model.monitoring.info.MonitoringCpu;
import com.tcs.model.monitoring.info.MonitoringInfo;
import com.tcs.model.monitoring.info.MonitoringMemory;
import com.tcs.monitoring.task.AbstractMonitoring;
import com.tcs.util.constant.SystemConstants;

/**
 * 监控程序{硬件}
 * 
 * @author wangbo
 */
public class MonitoringHardServersImpl extends AbstractMonitoring {

	private final Logger logger = LoggerFactory.getLogger(MonitoringHardServersImpl.class);

	private MonitoringInfo monitoringInfo = new MonitoringInfo();

	private MonitoringMemory monitoringMemory = new MonitoringMemory();

	private MonitoringCpu[] monitoringCpu = null;

	private int memSizeKB = 5125; // 内存警戒值

	// CPU个数, CPU警戒值
	private double cpuSize, cpuJingJie, cpuTotal = 0D;

	private void monitoringServers() {
		try {
			monitoringInfo = (MonitoringInfo) abstractMonitoringInfo;
			cpu();
			memory();
		} catch (SigarException e) {
			logger.error("", e);
		} finally {
			logger.info("{} , {} , {} , {} , {} , {}", new Object[]{
					monitoringInfo.getMonitoringMemory().getMemUsed(),
					monitoringInfo.getMonitoringMemory().getMemFree(),
					cpuTotal,
					new Date().getTime(),
					monitoringInfo.getMonitoringProperty().getHostName(),
					monitoringInfo.getMonitoringProperty().getIp()
			});
		}
	}

	private boolean checkParams(MonitoringInfo monitoringInfo) {
		initParams();
		monitoringInfo.setMessage(null);
		// 内存
		long free = monitoringInfo.getMonitoringMemory().getMemFree();
		if (memSizeKB >= free) {
			monitoringInfo.setMessage("警告: 内存使用率已耗尽!");
			ifInitParams(monitoringInfo);
			return true;
		}
		MonitoringCpu[] cpuArray = monitoringInfo.getMonitoringCpu();
		// CPU
		cpuSize = cpuArray.length;
		for (MonitoringCpu cpu : cpuArray) {
			cpuJingJie += cpu.getCpuCombined();
		}
		if (cpuSize - 0.5 <= cpuJingJie) {
			monitoringInfo.setMessage("警告: CPU使用率达到警戒值!");
			ifInitParams(monitoringInfo);
			return true;
		}
		return false;
	}

	/**
	 * 初始化参数
	 * 
	 * @param monitoringInfo
	 */
	private void ifInitParams(MonitoringInfo monitoringInfo) {
		monitoringInfo.setSubject(monitoringInfo.getMonitoringProperty().getIp() + " 节点 " + "主机名 : "
				+ monitoringInfo.getMonitoringProperty().getHostName() + "监控程序发现 : " + monitoringInfo.getMessage());
		monitoringInfo.setContent(monitoringInfo.toString());
	}

	private void initParams() {
		cpuSize = 0;
		cpuJingJie = 0; // 初始化
		cpuTotal = 0;	// CPU使用总量
	}

	private void memory() throws SigarException {
		Sigar sigar = new Sigar();
		Mem mem = sigar.getMem();
		monitoringMemory.setMemFree(mem.getFree() / 1024L); // 当前内存剩余量
		monitoringMemory.setMemTotal(mem.getTotal() / 1024L); // 内存总量
		monitoringMemory.setMemUsed(mem.getUsed() / 1024L); // 当前内存使用量
		monitoringInfo.setMonitoringMemory(monitoringMemory);
		// // 内存总量
		// System.out.println("---------------------内存总量: " + mem.getTotal() /
		// 1024L + "K av");
		// // 当前内存使用量
		// System.out.println("当前内存使用量: " + mem.getUsed() / 1024L + "K used");
		// // 当前内存剩余量
		// System.out.println("当前内存剩余量: " + mem.getFree() / 1024L + "K free");
		// Swap swap = sigar.getSwap();
		// // 交换区总量
		// System.out.println("交换区总量: " + swap.getTotal() / 1024L + "K av");
		// // 当前交换区使用量
		// System.out.println("当前交换区使用量: " + swap.getUsed() / 1024L + "K used");
		// // 当前交换区剩余量
		// System.out.println("当前交换区剩余量: " + swap.getFree() / 1024L + "K free");
	}

	private void cpu() throws SigarException {
		Sigar sigar = new Sigar();
		CpuInfo infos[] = sigar.getCpuInfoList();
		CpuPerc cpuList[] = null;
		cpuList = sigar.getCpuPercList();
		monitoringCpu = new MonitoringCpu[cpuList.length];
		for (int i = 0; i < infos.length; i++) {// 不管是单块CPU还是多CPU都适用
			// CpuInfo info = infos[i];
			// System.out.println("第" + (i + 1) + "块CPU信息");
			// System.out.println("CPU的总量MHz: " + info.getMhz());// CPU的总量MHz
			// System.out.println("CPU生产商: " + info.getVendor());//
			// 获得CPU的卖主，如：Intel
			// System.out.println("CPU类别: " + info.getModel());//
			// 获得CPU的类别，如：Celeron
			// System.out.println("CPU缓存数量: " + info.getCacheSize());// 缓冲存储器数量
			// printCpuPerc(cpuList[i]);
			monitoringCpu[i] = new MonitoringCpu(cpuList[i].getUser(), cpuList[i].getSys(), cpuList[i].getWait(),
					cpuList[i].getCombined());
			cpuTotal += cpuList[i].getCombined();
		}
		monitoringInfo.setMonitoringCpu(monitoringCpu);
	}

	// private void printCpuPerc(CpuPerc cpu) {
	// System.out.println("CPU用户使用率: " + cpu.getUser() +
	// "======================================================" +
	// CpuPerc.format(cpu.getUser()));// 用户使用率
	// System.out.println("CPU系统使用率: " + CpuPerc.format(cpu.getSys()));// 系统使用率
	// System.out.println("CPU当前等待率: " + CpuPerc.format(cpu.getWait()));// 当前等待率
	// System.out.println("CPU当前错误率: " + CpuPerc.format(cpu.getNice()));//
	// System.out.println("CPU当前空闲率: " + CpuPerc.format(cpu.getIdle()));// 当前空闲率
	// System.out.println("CPU总的使用率: " + CpuPerc.format(cpu.getCombined()));//
	// 总的使用率
	// }

	// private static void os() {
	// OperatingSystem OS = OperatingSystem.getInstance();
	// // 操作系统内核类型如： 386、486、586等x86
	// System.out.println("操作系统: " + OS.getArch());
	// System.out.println("操作系统CpuEndian(): " + OS.getCpuEndian());//
	// System.out.println("操作系统DataModel(): " + OS.getDataModel());//
	// // 系统描述
	// System.out.println("操作系统的描述: " + OS.getDescription());
	// // 操作系统类型
	// // System.out.println("OS.getName(): " + OS.getName());
	// // System.out.println("OS.getPatchLevel(): " + OS.getPatchLevel());//
	// // 操作系统的卖主
	// System.out.println("操作系统的卖主: " + OS.getVendor());
	// // 卖主名称
	// System.out.println("操作系统的卖主名: " + OS.getVendorCodeName());
	// // 操作系统名称
	// System.out.println("操作系统名称: " + OS.getVendorName());
	// // 操作系统卖主类型
	// System.out.println("操作系统卖主类型: " + OS.getVendorVersion());
	// // 操作系统的版本号
	// System.out.println("操作系统的版本号: " + OS.getVersion());
	// }

	// private static void who() throws SigarException {
	// Sigar sigar = new Sigar();
	// Who who[] = sigar.getWhoList();
	// if (who != null && who.length > 0) {
	// for (int i = 0; i < who.length; i++) {
	// // System.out.println("当前系统进程表中的用户名" + String.valueOf(i));
	// Who _who = who[i];
	// System.out.println("用户控制台: " + _who.getDevice());
	// System.out.println("用户host: " + _who.getHost());
	// // System.out.println("getTime(): " + _who.getTime());
	// // 当前系统进程表中的用户名
	// System.out.println("当前系统进程表中的用户名: " + _who.getUser());
	// }
	// }
	// }

	// private static void file() throws Exception {
	// Sigar sigar = new Sigar();
	// FileSystem fslist[] = sigar.getFileSystemList();
	// for (int i = 0; i < fslist.length; i++) {
	// System.out.println("分区的盘符名称" + i);
	// FileSystem fs = fslist[i];
	// // 分区的盘符名称
	// System.out.println("盘符名称: " + fs.getDevName());
	// // 分区的盘符名称
	// System.out.println("盘符路径: " + fs.getDirName());
	// System.out.println("盘符标志: " + fs.getFlags());//
	// // 文件系统类型，比如 FAT32、NTFS
	// System.out.println("盘符类型: " + fs.getSysTypeName());
	// // 文件系统类型名，比如本地硬盘、光驱、网络文件系统等
	// System.out.println("盘符类型名: " + fs.getTypeName());
	// // 文件系统类型
	// System.out.println("盘符文件系统类型: " + fs.getType());
	// FileSystemUsage usage = null;
	// usage = sigar.getFileSystemUsage(fs.getDirName());
	// switch (fs.getType()) {
	// case 0: // TYPE_UNKNOWN ：未知
	// break;
	// case 1: // TYPE_NONE
	// break;
	// case 2: // TYPE_LOCAL_DISK : 本地硬盘
	// // 文件系统总大小
	// System.out.println(fs.getDevName() + "总大小: " + usage.getTotal() + "KB");
	// // 文件系统剩余大小
	// System.out.println(fs.getDevName() + "剩余大小: " + usage.getFree() + "KB");
	// // 文件系统可用大小
	// System.out.println(fs.getDevName() + "可用大小: " + usage.getAvail() + "KB");
	// // 文件系统已经使用量
	// System.out.println(fs.getDevName() + "已经使用量: " + usage.getUsed() + "KB");
	// double usePercent = usage.getUsePercent() * 100D;
	// // 文件系统资源的利用率
	// System.out.println(fs.getDevName() + "资源的利用率: " + usePercent + "%");
	// break;
	// case 3:// TYPE_NETWORK ：网络
	// break;
	// case 4:// TYPE_RAM_DISK ：闪存
	// break;
	// case 5:// TYPE_CDROM ：光驱
	// break;
	// case 6:// TYPE_SWAP ：页面交换
	// break;
	// }
	// System.out.println(fs.getDevName() + "读出： " + usage.getDiskReads());
	// System.out.println(fs.getDevName() + "写入： " + usage.getDiskWrites());
	// }
	// return;
	// }

	// private static void net() throws Exception {
	// Sigar sigar = new Sigar();
	// String ifNames[] = sigar.getNetInterfaceList();
	// for (int i = 0; i < ifNames.length; i++) {
	// String name = ifNames[i];
	// NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name);
	// System.out.println("网络设备名: " + name);// 网络设备名
	// System.out.println("IP地址: " + ifconfig.getAddress());// IP地址
	// System.out.println("子网掩码: " + ifconfig.getNetmask());// 子网掩码
	// if ((ifconfig.getFlags() & 1L) <= 0L) {
	// System.out.println("!IFF_UP...skipping getNetInterfaceStat");
	// continue;
	// }
	// NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);
	// System.out.println(name + "接收的总包裹数:" + ifstat.getRxPackets());// 接收的总包裹数
	// System.out.println(name + "发送的总包裹数:" + ifstat.getTxPackets());// 发送的总包裹数
	// System.out.println(name + "接收到的总字节数:" + ifstat.getRxBytes());// 接收到的总字节数
	// System.out.println(name + "发送的总字节数:" + ifstat.getTxBytes());// 发送的总字节数
	// System.out.println(name + "接收到的错误包数:" + ifstat.getRxErrors());// 接收到的错误包数
	// System.out.println(name + "发送数据包时的错误数:" + ifstat.getTxErrors());//
	// 发送数据包时的错误数
	// System.out.println(name + "接收时丢弃的包数:" + ifstat.getRxDropped());//
	// 接收时丢弃的包数
	// System.out.println(name + "发送时丢弃的包数:" + ifstat.getTxDropped());//
	// 发送时丢弃的包数
	// }
	// }

	// private static void ethernet() throws SigarException {
	// Sigar sigar = null;
	// sigar = new Sigar();
	// String[] ifaces = sigar.getNetInterfaceList();
	// for (int i = 0; i < ifaces.length; i++) {
	// NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]);
	// if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress()) || (cfg.getFlags()
	// & NetFlags.IFF_LOOPBACK) != 0
	// || NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) {
	// continue;
	// }
	// System.out.println(cfg.getName() + "IP地址:" + cfg.getAddress());// IP地址
	// System.out.println(cfg.getName() + "网关广播地址:" + cfg.getBroadcast());//
	// 网关广播地址
	// System.out.println(cfg.getName() + "网卡MAC地址:" + cfg.getHwaddr());//
	// 网卡MAC地址
	// System.out.println(cfg.getName() + "子网掩码:" + cfg.getNetmask());// 子网掩码
	// System.out.println(cfg.getName() + "网卡描述信息:" + cfg.getDescription());//
	// 网卡描述信息
	// System.out.println(cfg.getName() + "网卡类型" + cfg.getType());//
	// }
	// }

	public void print() {
		// System信息，从jvm获取
		// property();
		// System.out.println("----------------------------------");
		// cpu信息
		// cpu();
		// System.out.println("----------------------------------");
		// 内存信息
		// memory();
		// System.out.println("----------------------------------");
		// 操作系统信息
		// os();
		// System.out.println("----------------------------------");
		// 用户信息
		// who();
		// System.out.println("----------------------------------");
		// 文件系统信息
		// file();
		// System.out.println("----------------------------------");
		// 网络信息
		// net();
		// System.out.println("----------------------------------");
		// 以太网信息
		// ethernet();
		// System.out.println("----------------------------------");
	}

	@Override
	public void monitoring() {
		try {
			monitoringServers();
			if (checkParams(monitoringInfo)) {
				iSendService.sendObject(monitoringInfo , 0 , SystemConstants.MontioringConstants.HARD);
			}
		} catch (Exception e) {
			logger.error("" , e);
		}
	}

}